using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using PickGold.Charting;
using PickGold.Charting.Utilities;

namespace PickGold.Charting.ChartTypes
{
	internal class BoxPlotChart : IChartType, IDisposable
	{
		protected Axis hAxis;
		protected bool showSideBySide = true;
		protected Axis vAxis;

		public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list)
		{
		}

		private static void BoxPlotAddUnusual(ref DataPoint boxPoint, List<double> yValues)
		{
			ArrayList list = new ArrayList();
			foreach (double num in yValues)
			{
				if ((num < boxPoint.YValues[0]) || (num > boxPoint.YValues[1]))
				{
					list.Add(num);
				}
			}
			if (list.Count > 0)
			{
				double[] numArray = new double[6 + list.Count];
				for (int i = 0; i < 6; i++)
				{
					numArray[i] = boxPoint.YValues[i];
				}
				for (int j = 0; j < list.Count; j++)
				{
					numArray[6 + j] = (double)list[j];
				}
				boxPoint.YValues = numArray;
			}
		}

		internal static void CalculateBoxPlotFromLinkedSeries(Series boxPlotSeries)
		{
			if (string.Compare(boxPlotSeries.ChartTypeName, "BoxPlot", StringComparison.OrdinalIgnoreCase) == 0)
			{
				if (boxPlotSeries.IsCustomPropertySet("BoxPlotSeries"))
				{
					string[] strArray = boxPlotSeries["BoxPlotSeries"].Split(new char[] { ';' });
					boxPlotSeries.Points.Clear();
					int num = 0;
					foreach (string str in strArray)
					{
						boxPlotSeries.Points.AddY((double)0.0);
						boxPlotSeries.Points[num++]["BoxPlotSeries"] = str.Trim();
					}
				}
				for (int i = 0; i < boxPlotSeries.Points.Count; i++)
				{
					DataPoint boxPoint = boxPlotSeries.Points[i];
					if (boxPoint.IsCustomPropertySet("BoxPlotSeries"))
					{
						string name = boxPoint["BoxPlotSeries"];
						string valueName = "Y";
						int index = name.IndexOf(":", StringComparison.OrdinalIgnoreCase);
						if (index >= 0)
						{
							valueName = name.Substring(index + 1);
							name = name.Substring(0, index);
						}
						Chart chart = boxPlotSeries.Chart;
						if (chart != null)
						{
							if (chart.Series.IndexOf(name) == -1)
							{
								throw new InvalidOperationException(SR.ExceptionCustomAttributeSeriesNameNotFound("BoxPlotSeries", name));
							}
							Series linkedSeries = chart.Series[name];
							CalculateBoxPlotValues(ref boxPoint, linkedSeries, valueName);
						}
					}
				}
			}
		}

		private static void CalculateBoxPlotValues(ref DataPoint boxPoint, Series linkedSeries, string valueName)
		{
			if (linkedSeries.Points.Count != 0)
			{
				double num = 0.0;
				int capacity = 0;
				foreach (DataPoint point in linkedSeries.Points)
				{
					if (!point.IsEmpty)
					{
						num += point.GetValueByName(valueName);
						capacity++;
					}
				}
				num /= (double)capacity;
				List<double> yValues = new List<double>(capacity);
				foreach (DataPoint point2 in linkedSeries.Points)
				{
					if (!point2.IsEmpty)
					{
						yValues.Add(point2.IsEmpty ? double.NaN : point2.GetValueByName(valueName));
					}
				}
				double[] requiredPercentile = new double[] { 10.0, 90.0, 25.0, 75.0, 50.0 };
				string s = boxPoint.IsCustomPropertySet("BoxPlotPercentile") ? boxPoint["BoxPlotPercentile"] : string.Empty;
				if (((s.Length == 0) && (boxPoint.series != null)) && boxPoint.series.IsCustomPropertySet("BoxPlotPercentile"))
				{
					s = boxPoint.series["BoxPlotPercentile"];
				}
				string str2 = boxPoint.IsCustomPropertySet("BoxPlotWhiskerPercentile") ? boxPoint["BoxPlotWhiskerPercentile"] : string.Empty;
				if (((str2.Length == 0) && (boxPoint.series != null)) && boxPoint.series.IsCustomPropertySet("BoxPlotWhiskerPercentile"))
				{
					str2 = boxPoint.series["BoxPlotWhiskerPercentile"];
				}
				if (s.Length > 0)
				{
					double num3;
					bool flag = double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out num3);
					if (flag)
					{
						requiredPercentile[2] = num3;
					}
					if ((!flag || (requiredPercentile[2] < 0.0)) || (requiredPercentile[2] > 50.0))
					{
						throw new InvalidOperationException(SR.ExceptionCustomAttributeIsNotInRange0to50("BoxPlotPercentile"));
					}
					requiredPercentile[3] = 100.0 - requiredPercentile[2];
				}
				if (str2.Length > 0)
				{
					double num4;
					bool flag2 = double.TryParse(str2, NumberStyles.Any, CultureInfo.InvariantCulture, out num4);
					if (flag2)
					{
						requiredPercentile[0] = num4;
					}
					if ((!flag2 || (requiredPercentile[0] < 0.0)) || (requiredPercentile[0] > 50.0))
					{
						throw new InvalidOperationException(SR.ExceptionCustomAttributeIsNotInRange0to50("BoxPlotPercentile"));
					}
					requiredPercentile[1] = 100.0 - requiredPercentile[0];
				}
				double[] numArray2 = CalculatePercentileValues(yValues, requiredPercentile);
				boxPoint.YValues[0] = numArray2[0];
				boxPoint.YValues[1] = numArray2[1];
				boxPoint.YValues[2] = numArray2[2];
				boxPoint.YValues[3] = numArray2[3];
				boxPoint.YValues[4] = num;
				boxPoint.YValues[5] = numArray2[4];
				bool flag3 = false;
				string strA = boxPoint.IsCustomPropertySet("BoxPlotShowUnusualValues") ? boxPoint["BoxPlotShowUnusualValues"] : string.Empty;
				if (((strA.Length == 0) && (boxPoint.series != null)) && boxPoint.series.IsCustomPropertySet("BoxPlotShowUnusualValues"))
				{
					strA = boxPoint.series["BoxPlotShowUnusualValues"];
				}
				if (strA.Length > 0)
				{
					if (string.Compare(strA, "True", StringComparison.OrdinalIgnoreCase) != 0)
					{
						if (string.Compare(strA, "False", StringComparison.OrdinalIgnoreCase) != 0)
						{
							throw new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("BoxPlotShowUnusualValues"));
						}
						flag3 = false;
					}
					else
					{
						flag3 = true;
					}
				}
				if (flag3)
				{
					BoxPlotAddUnusual(ref boxPoint, yValues);
				}
			}
		}

		private static double[] CalculatePercentileValues(List<double> yValues, double[] requiredPercentile)
		{
			double[] numArray = new double[5];
			yValues.Sort();
			int index = 0;
			foreach (double num2 in requiredPercentile)
			{
				double d = ((yValues.Count - 1.0) / 100.0) * num2;
				double num4 = Math.Floor(d);
				double num5 = d - num4;
				numArray[index] = 0.0;
				if (((int)num4) < yValues.Count)
				{
					numArray[index] += (1.0 - num5) * yValues[(int)num4];
				}
				if (((int)(num4 + 1.0)) < yValues.Count)
				{
					numArray[index] += num5 * yValues[((int)num4) + 1];
				}
				index++;
			}
			return numArray;
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
		}

		protected virtual void DrawBoxPlotMarks(ChartGraphics graph, ChartArea area, Series ser, DataPoint point, float xPosition, float width)
		{
			string markerStyle = "LINE";
			if (point.MarkerStyle != MarkerStyle.None)
			{
				markerStyle = point.MarkerStyle.ToString();
			}
			double logValue = this.vAxis.GetLogValue(point.YValues[0]);
			this.DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)logValue, 0f, width, false);
			logValue = this.vAxis.GetLogValue(point.YValues[1]);
			this.DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)logValue, 0f, width, false);
			markerStyle = "CIRCLE";
			if (point.MarkerStyle != MarkerStyle.None)
			{
				markerStyle = point.MarkerStyle.ToString();
			}
			for (int i = 6; i < point.YValues.Length; i++)
			{
				if (!double.IsNaN(point.YValues[i]))
				{
					logValue = this.vAxis.GetLogValue(point.YValues[i]);
					this.DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)logValue, 0f, width, false);
				}
			}
		}

		protected virtual void DrawBoxPlotMarks3D(ChartGraphics graph, ChartArea area, Series ser, DataPoint point, float xPosition, float width, float zPosition, float depth)
		{
			string markerStyle = "LINE";
			if (point.MarkerStyle != MarkerStyle.None)
			{
				markerStyle = point.MarkerStyle.ToString();
			}
			double logValue = this.vAxis.GetLogValue(point.YValues[0]);
			this.DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)logValue, zPosition + (depth / 2f), width, true);
			logValue = this.vAxis.GetLogValue(point.YValues[1]);
			this.DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)logValue, zPosition + (depth / 2f), width, true);
			markerStyle = "CIRCLE";
			if (point.MarkerStyle != MarkerStyle.None)
			{
				markerStyle = point.MarkerStyle.ToString();
			}
			for (int i = 6; i < point.YValues.Length; i++)
			{
				if (!double.IsNaN(point.YValues[i]))
				{
					logValue = this.vAxis.GetLogValue(point.YValues[i]);
					this.DrawBoxPlotSingleMarker(graph, area, point, markerStyle, xPosition, (float)logValue, zPosition + (depth / 2f), width, true);
				}
			}
		}

		private void DrawBoxPlotSingleMarker(ChartGraphics graph, ChartArea area, DataPoint point, string markerStyle, float xPosition, float yPosition, float zPosition, float width, bool draw3D)
		{
			markerStyle = markerStyle.ToUpper(CultureInfo.InvariantCulture);
			if (((markerStyle.Length > 0) && (string.Compare(markerStyle, "None", StringComparison.OrdinalIgnoreCase) != 0)) && ((yPosition <= this.vAxis.ViewMaximum) && (yPosition >= this.vAxis.ViewMinimum)))
			{
				yPosition = (float)this.vAxis.GetLinearPosition((double)yPosition);
				if (draw3D)
				{
					Point3D[] points = new Point3D[] { new Point3D(xPosition, yPosition, zPosition) };
					area.matrix3D.TransformPoints(points);
					xPosition = points[0].X;
					yPosition = points[0].Y;
				}
				Color borderColor = point.BorderColor;
				if (borderColor == Color.Empty)
				{
					borderColor = point.Color;
				}
				if (string.Compare(markerStyle, "Line", StringComparison.OrdinalIgnoreCase) == 0)
				{
					graph.DrawLineRel(borderColor, point.BorderWidth, point.BorderDashStyle, new PointF(xPosition - (width / 4f), yPosition), new PointF(xPosition + (width / 4f), yPosition), (point.series != null) ? point.series.ShadowColor : Color.Empty, (point.series != null) ? point.series.ShadowOffset : 0);
				}
				else
				{
					MarkerStyle style = (MarkerStyle)Enum.Parse(typeof(MarkerStyle), markerStyle, true);
					SizeF ef = this.GetMarkerSize(graph, area.Common, area, point, point.MarkerSize, point.MarkerImage);
					Color markerColor = (point.MarkerColor == Color.Empty) ? point.BorderColor : point.MarkerColor;
					if (markerColor == Color.Empty)
					{
						markerColor = point.Color;
					}
					graph.DrawMarkerRel(new PointF(xPosition, yPosition), style, point.MarkerSize, markerColor, point.MarkerBorderColor, point.MarkerBorderWidth, point.MarkerImage, point.MarkerImageTransparentColor, (point.series != null) ? point.series.ShadowOffset : 0, (point.series != null) ? point.series.ShadowColor : Color.Empty, new RectangleF(xPosition, yPosition, ef.Width, ef.Height));
				}
			}
		}

		protected virtual void DrawLabel(CommonElements common, ChartArea area, ChartGraphics graph, Series ser, DataPoint point, PointF position, int pointIndex)
		{
			if ((ser.IsValueShownAsLabel || point.IsValueShownAsLabel) || (point.Label.Length > 0))
			{
				using (StringFormat format = new StringFormat())
				{
					string str;
					format.Alignment = StringAlignment.Near;
					format.LineAlignment = StringAlignment.Center;
					if (point.LabelAngle == 0)
					{
						format.Alignment = StringAlignment.Center;
						format.LineAlignment = StringAlignment.Far;
					}
					if (point.Label.Length == 0)
					{
						str = ValueConverter.FormatValue(ser.Chart, point, point.Tag, point.YValues[0], point.LabelFormat, ser.YValueType, ChartElementType.DataPoint);
					}
					else
					{
						str = point.ReplaceKeywords(point.Label);
					}
					SizeF markerSize = new SizeF(0f, 0f);
					if (point.MarkerStyle != MarkerStyle.None)
					{
						markerSize = graph.GetRelativeSize(new SizeF((float)point.MarkerSize, (float)point.MarkerSize));
						position.Y -= markerSize.Height / 2f;
					}
					int labelAngle = point.LabelAngle;
					if (str.Trim().Length != 0)
					{
						SizeF empty = SizeF.Empty;
						if (ser.SmartLabelStyle.Enabled)
						{
							empty = graph.GetRelativeSize(graph.MeasureString(str, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic));
							position = area.smartLabels.AdjustSmartLabelPosition(common, graph, area, ser.SmartLabelStyle, position, empty, format, position, markerSize, LabelAlignmentStyles.Top);
							labelAngle = 0;
						}
						if (!position.IsEmpty)
						{
							if (empty.IsEmpty)
							{
								empty = graph.GetRelativeSize(graph.MeasureString(str, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic));
							}
							RectangleF backPosition = RectangleF.Empty;
							SizeF size = new SizeF(empty.Width, empty.Height);
							size.Height += empty.Height / 8f;
							size.Width += size.Width / ((float)str.Length);
							backPosition = PointChart.GetLabelPosition(graph, position, size, format, true);
							using (Brush brush = new SolidBrush(point.LabelForeColor))
							{
								graph.DrawPointLabelStringRel(common, str, point.Font, brush, position, format, labelAngle, backPosition, point.LabelBackColor, point.LabelBorderColor, point.LabelBorderWidth, point.LabelBorderDashStyle, ser, point, pointIndex - 1);
							}
						}
					}
				}
			}
		}

		public virtual Image GetImage(ChartTypeRegistry registry)
		{
			return (Image)registry.ResourceManager.GetObject(this.Name + "ChartType");
		}

		public virtual LegendImageStyle GetLegendImageStyle(Series series)
		{
			return LegendImageStyle.Rectangle;
		}

		protected virtual SizeF GetMarkerSize(ChartGraphics graph, CommonElements common, ChartArea area, DataPoint point, int markerSize, string markerImage)
		{
			SizeF size = new SizeF((float)markerSize, (float)markerSize);
			if ((graph != null) && (graph.Graphics != null))
			{
				size.Width = (markerSize * graph.Graphics.DpiX) / 96f;
				size.Height = (markerSize * graph.Graphics.DpiY) / 96f;
			}
			if (markerImage.Length > 0)
			{
				common.ImageLoader.GetAdjustedImageSize(markerImage, graph.Graphics, ref size);
			}
			return size;
		}

		public virtual double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex)
		{
			return point.YValues[yValueIndex];
		}

		public virtual void Paint(ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
			this.ProcessChartType(false, graph, common, area, seriesToDraw);
		}

		protected virtual void ProcessChartType(bool selection, ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
			if (area.Area3DStyle.Enable3D)
			{
				this.ProcessChartType3D(selection, graph, common, area, seriesToDraw);
			}
			else
			{
				List<string> seriesFromChartType = area.GetSeriesFromChartType(this.Name);
				bool flag = ChartHelper.IndexedSeries(area.Common, seriesFromChartType.ToArray());
				int num = 0;
				foreach (Series series in common.DataManager.Series)
				{
					if (((string.Compare(series.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase) != 0) || (series.ChartArea != area.Name)) || !series.IsVisible())
					{
						continue;
					}
					this.hAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName);
					this.vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName);
					double interval = flag ? 1.0 : area.GetPointsInterval(this.hAxis.IsLogarithmic, this.hAxis.logarithmBase);
					bool showSideBySide = this.showSideBySide;
					if (series.IsCustomPropertySet("DrawSideBySide"))
					{
						string strA = series["DrawSideBySide"];
						if (string.Compare(strA, "False", StringComparison.OrdinalIgnoreCase) == 0)
						{
							showSideBySide = false;
						}
						else if (string.Compare(strA, "True", StringComparison.OrdinalIgnoreCase) == 0)
						{
							showSideBySide = true;
						}
						else if (string.Compare(strA, "Auto", StringComparison.OrdinalIgnoreCase) != 0)
						{
							throw new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid);
						}
					}
					double count = seriesFromChartType.Count;
					if (!showSideBySide)
					{
						count = 1.0;
					}
					float width = (float)(series.GetPointWidth(graph, this.hAxis, interval, 0.8) / count);
					if (!selection)
					{
						common.Chart.CallOnPrePaint(new ChartPaintEventArgs(series, graph, common, area.PlotAreaPosition));
					}
					int pointIndex = 1;
					foreach (DataPoint point in series.Points)
					{
						if (point.YValues.Length < this.YValuesPerPoint)
						{
							throw new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)));
						}
						point.positionRel = new PointF(float.NaN, float.NaN);
						float x = 0f;
						double xValue = point.XValue;
						if (flag)
						{
							xValue = pointIndex;
							x = (((float)(this.hAxis.GetPosition((double)pointIndex) - ((width * count) / 2.0))) + (width / 2f)) + (num * width);
						}
						else if (showSideBySide)
						{
							x = (((float)(this.hAxis.GetPosition(xValue) - ((width * count) / 2.0))) + (width / 2f)) + (num * width);
						}
						else
						{
							x = (float)this.hAxis.GetPosition(xValue);
						}
						double logValue = this.vAxis.GetLogValue(point.YValues[0]);
						double num9 = this.vAxis.GetLogValue(point.YValues[1]);
						xValue = this.hAxis.GetLogValue(xValue);
						if ((((xValue < this.hAxis.ViewMinimum) || (xValue > this.hAxis.ViewMaximum)) || ((logValue < this.vAxis.ViewMinimum) && (num9 < this.vAxis.ViewMinimum))) || ((logValue > this.vAxis.ViewMaximum) && (num9 > this.vAxis.ViewMaximum)))
						{
							pointIndex++;
							continue;
						}
						double axisValue = this.vAxis.GetLogValue(point.YValues[0]);
						double linearPosition = this.vAxis.GetLogValue(point.YValues[1]);
						if (linearPosition > this.vAxis.ViewMaximum)
						{
							linearPosition = this.vAxis.ViewMaximum;
						}
						if (linearPosition < this.vAxis.ViewMinimum)
						{
							linearPosition = this.vAxis.ViewMinimum;
						}
						linearPosition = (float)this.vAxis.GetLinearPosition(linearPosition);
						if (axisValue > this.vAxis.ViewMaximum)
						{
							axisValue = this.vAxis.ViewMaximum;
						}
						if (axisValue < this.vAxis.ViewMinimum)
						{
							axisValue = this.vAxis.ViewMinimum;
						}
						axisValue = this.vAxis.GetLinearPosition(axisValue);
						point.positionRel = new PointF(x, (float)Math.Min(linearPosition, axisValue));
						if (common.ProcessModePaint)
						{
							bool flag3 = false;
							if ((xValue == this.hAxis.ViewMinimum) || (xValue == this.hAxis.ViewMaximum))
							{
								graph.SetClip(area.PlotAreaPosition.ToRectangleF());
								flag3 = true;
							}
							Color borderColor = point.BorderColor;
							if (borderColor == Color.Empty)
							{
								borderColor = point.Color;
							}
							graph.StartHotRegion(point);
							graph.DrawLineRel(borderColor, point.BorderWidth, point.BorderDashStyle, new PointF(x, (float)axisValue), new PointF(x, (float)this.vAxis.GetPosition(point.YValues[2])), series.ShadowColor, series.ShadowOffset);
							graph.DrawLineRel(borderColor, point.BorderWidth, point.BorderDashStyle, new PointF(x, (float)linearPosition), new PointF(x, (float)this.vAxis.GetPosition(point.YValues[3])), series.ShadowColor, series.ShadowOffset);
							RectangleF empty = RectangleF.Empty;
							empty.X = x - (width / 2f);
							empty.Width = width;
							empty.Y = (float)this.vAxis.GetPosition(point.YValues[3]);
							empty.Height = (float)Math.Abs((double)(empty.Y - this.vAxis.GetPosition(point.YValues[2])));
							graph.FillRectangleRel(empty, point.Color, point.BackHatchStyle, point.BackImage, point.BackImageWrapMode, point.BackImageTransparentColor, point.BackImageAlignment, point.BackGradientStyle, point.BackSecondaryColor, point.BorderColor, point.BorderWidth, point.BorderDashStyle, series.ShadowColor, series.ShadowOffset, PenAlignment.Inset);
							bool flag4 = true;
							if (point.IsCustomPropertySet("BoxPlotShowAverage") || series.IsCustomPropertySet("BoxPlotShowAverage"))
							{
								string str2 = series["BoxPlotShowAverage"];
								if (point.IsCustomPropertySet("BoxPlotShowAverage"))
								{
									str2 = point["BoxPlotShowAverage"];
								}
								if (string.Compare(str2, "True", StringComparison.OrdinalIgnoreCase) != 0)
								{
									if (string.Compare(str2, "False", StringComparison.OrdinalIgnoreCase) != 0)
									{
										throw new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(point["BoxPlotShowAverage"], "BoxPlotShowAverage"));
									}
									flag4 = false;
								}
							}
							SizeF relativeSize = graph.GetRelativeSize(new SizeF((float)point.BorderWidth, (float)point.BorderWidth));
							if (point.BorderColor == Color.Empty)
							{
								relativeSize.Height = 0f;
								relativeSize.Width = 0f;
							}
							Color color = borderColor;
							if (color == point.Color)
							{
								if (Math.Sqrt((double)(((point.Color.R * point.Color.R) + (point.Color.G * point.Color.G)) + (point.Color.B * point.Color.B))) > 220.0)
								{
									color = ChartGraphics.GetGradientColor(point.Color, Color.Black, 0.4);
								}
								else
								{
									color = ChartGraphics.GetGradientColor(point.Color, Color.White, 0.4);
								}
							}
							if (!double.IsNaN(point.YValues[4]) && flag4)
							{
								graph.DrawLineRel(color, 1, ChartDashStyle.Solid, new PointF(empty.Left + relativeSize.Width, (float)this.vAxis.GetPosition(point.YValues[4])), new PointF(empty.Right - relativeSize.Width, (float)this.vAxis.GetPosition(point.YValues[4])), Color.Empty, 0);
							}
							bool flag5 = true;
							if (point.IsCustomPropertySet("BoxPlotShowMedian") || series.IsCustomPropertySet("BoxPlotShowMedian"))
							{
								string str3 = series["BoxPlotShowMedian"];
								if (point.IsCustomPropertySet("BoxPlotShowMedian"))
								{
									str3 = point["BoxPlotShowMedian"];
								}
								if (string.Compare(str3, "True", StringComparison.OrdinalIgnoreCase) != 0)
								{
									if (string.Compare(str3, "False", StringComparison.OrdinalIgnoreCase) != 0)
									{
										throw new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(point["BoxPlotShowMedian"], "BoxPlotShowMedian"));
									}
									flag5 = false;
								}
							}
							if (!double.IsNaN(point.YValues[5]) && flag5)
							{
								float position = (float)this.vAxis.GetPosition(point.YValues[5]);
								float num14 = (empty.Width - (relativeSize.Width * 2f)) / 9f;
								SizeF ef3 = graph.GetRelativeSize(new SizeF(2f, 2f));
								num14 = Math.Max(num14, ef3.Width);
								for (float i = empty.Left + relativeSize.Width; i < (empty.Right - relativeSize.Width); i += num14 * 2f)
								{
									graph.DrawLineRel(color, 1, ChartDashStyle.Solid, new PointF(i, position), new PointF(Math.Min(empty.Right, i + num14), position), Color.Empty, 0);
								}
							}
							this.DrawBoxPlotMarks(graph, area, series, point, x, width);
							graph.EndHotRegion();
							if (flag3)
							{
								graph.ResetClip();
							}
						}
						if (common.ProcessModeRegions)
						{
							RectangleF rectSize = RectangleF.Empty;
							rectSize.X = x - (width / 2f);
							rectSize.Y = (float)Math.Min(linearPosition, axisValue);
							rectSize.Width = width;
							rectSize.Height = ((float)Math.Max(linearPosition, axisValue)) - rectSize.Y;
							common.HotRegionsList.AddHotRegion(rectSize, point, series.Name, pointIndex - 1);
						}
						pointIndex++;
					}
					if (!selection)
					{
						pointIndex = 1;
						foreach (DataPoint point2 in series.Points)
						{
							float num16 = 0f;
							double num17 = point2.XValue;
							if (flag)
							{
								num17 = pointIndex;
								num16 = (((float)(this.hAxis.GetPosition((double)pointIndex) - ((width * count) / 2.0))) + (width / 2f)) + (num * width);
							}
							else if (showSideBySide)
							{
								num16 = (((float)(this.hAxis.GetPosition(num17) - ((width * count) / 2.0))) + (width / 2f)) + (num * width);
							}
							else
							{
								num16 = (float)this.hAxis.GetPosition(num17);
							}
							double num18 = this.vAxis.GetLogValue(point2.YValues[0]);
							double num19 = this.vAxis.GetLogValue(point2.YValues[1]);
							num17 = this.hAxis.GetLogValue(num17);
							if ((((num17 < this.hAxis.ViewMinimum) || (num17 > this.hAxis.ViewMaximum)) || ((num18 < this.vAxis.ViewMinimum) && (num19 < this.vAxis.ViewMinimum))) || ((num18 > this.vAxis.ViewMaximum) && (num19 > this.vAxis.ViewMaximum)))
							{
								pointIndex++;
								continue;
							}
							double maxValue = double.MaxValue;
							for (int j = 0; j < point2.YValues.Length; j++)
							{
								if (!double.IsNaN(point2.YValues[j]))
								{
									double viewMaximum = this.vAxis.GetLogValue(point2.YValues[j]);
									if (viewMaximum > this.vAxis.ViewMaximum)
									{
										viewMaximum = this.vAxis.ViewMaximum;
									}
									if (viewMaximum < this.vAxis.ViewMinimum)
									{
										viewMaximum = this.vAxis.ViewMinimum;
									}
									viewMaximum = (float)this.vAxis.GetLinearPosition(viewMaximum);
									maxValue = Math.Min(maxValue, viewMaximum);
								}
							}
							SizeF ef5 = graph.GetRelativeSize(new SizeF((float)point2.MarkerSize, (float)point2.MarkerSize));
							maxValue -= ef5.Height / 2f;
							graph.StartHotRegion(point2, true);
							this.DrawLabel(common, area, graph, series, point2, new PointF(num16, (float)maxValue), pointIndex);
							graph.EndHotRegion();
							pointIndex++;
						}
					}
					if (!selection)
					{
						common.Chart.CallOnPostPaint(new ChartPaintEventArgs(series, graph, common, area.PlotAreaPosition));
					}
					if (showSideBySide)
					{
						num++;
					}
				}
			}
		}

		protected virtual void ProcessChartType3D(bool selection, ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
			List<string> seriesFromChartType = area.GetSeriesFromChartType(this.Name);
			bool flag = ChartHelper.IndexedSeries(common, seriesFromChartType.ToArray());
			int num = 0;
			foreach (Series series in common.DataManager.Series)
			{
				float num5;
				float num6;
				if (((string.Compare(series.ChartTypeName, this.Name, StringComparison.OrdinalIgnoreCase) != 0) || (series.ChartArea != area.Name)) || !series.IsVisible())
				{
					continue;
				}
				if (series.YValuesPerPoint < 6)
				{
					throw new ArgumentException(SR.ExceptionChartTypeRequiresYValues("BoxPlot", "6"));
				}
				bool showSideBySide = this.showSideBySide;
				if (series.IsCustomPropertySet("DrawSideBySide"))
				{
					string strA = series["DrawSideBySide"];
					if (string.Compare(strA, "False", StringComparison.OrdinalIgnoreCase) == 0)
					{
						showSideBySide = false;
					}
					else if (string.Compare(strA, "True", StringComparison.OrdinalIgnoreCase) == 0)
					{
						showSideBySide = true;
					}
					else if (string.Compare(strA, "Auto", StringComparison.OrdinalIgnoreCase) != 0)
					{
						throw new InvalidOperationException(SR.ExceptionAttributeDrawSideBySideInvalid);
					}
				}
				double count = seriesFromChartType.Count;
				if (!showSideBySide)
				{
					count = 1.0;
				}
				this.hAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName);
				this.vAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName);
				double interval = flag ? 1.0 : area.GetPointsInterval(this.hAxis.IsLogarithmic, this.hAxis.logarithmBase);
				float width = (float)(series.GetPointWidth(graph, this.hAxis, interval, 0.8) / count);
				if (!selection)
				{
					common.Chart.CallOnPrePaint(new ChartPaintEventArgs(series, graph, common, area.PlotAreaPosition));
				}
				area.GetSeriesZPositionAndDepth(series, out num5, out num6);
				int pointIndex = 1;
				foreach (DataPoint point in series.Points)
				{
					if (point.YValues.Length < this.YValuesPerPoint)
					{
						throw new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)));
					}
					point.positionRel = new PointF(float.NaN, float.NaN);
					float x = 0f;
					double xValue = point.XValue;
					if (flag)
					{
						xValue = pointIndex;
						x = (((float)(this.hAxis.GetPosition((double)pointIndex) - ((width * count) / 2.0))) + (width / 2f)) + (num * width);
					}
					else if (showSideBySide)
					{
						x = (((float)(this.hAxis.GetPosition(xValue) - ((width * count) / 2.0))) + (width / 2f)) + (num * width);
					}
					else
					{
						x = (float)this.hAxis.GetPosition(xValue);
					}
					double logValue = this.vAxis.GetLogValue(point.YValues[0]);
					double num11 = this.vAxis.GetLogValue(point.YValues[1]);
					xValue = this.hAxis.GetLogValue(xValue);
					if ((((xValue < this.hAxis.ViewMinimum) || (xValue > this.hAxis.ViewMaximum)) || ((logValue < this.vAxis.ViewMinimum) && (num11 < this.vAxis.ViewMinimum))) || ((logValue > this.vAxis.ViewMaximum) && (num11 > this.vAxis.ViewMaximum)))
					{
						pointIndex++;
						continue;
					}
					double axisValue = this.vAxis.GetLogValue(point.YValues[1]);
					double linearPosition = this.vAxis.GetLogValue(point.YValues[0]);
					if (axisValue > this.vAxis.ViewMaximum)
					{
						axisValue = this.vAxis.ViewMaximum;
					}
					if (axisValue < this.vAxis.ViewMinimum)
					{
						axisValue = this.vAxis.ViewMinimum;
					}
					axisValue = (float)this.vAxis.GetLinearPosition(axisValue);
					if (linearPosition > this.vAxis.ViewMaximum)
					{
						linearPosition = this.vAxis.ViewMaximum;
					}
					if (linearPosition < this.vAxis.ViewMinimum)
					{
						linearPosition = this.vAxis.ViewMinimum;
					}
					linearPosition = this.vAxis.GetLinearPosition(linearPosition);
					point.positionRel = new PointF(x, (float)Math.Min(axisValue, linearPosition));
					Point3D[] points = new Point3D[] { new Point3D(x, (float)linearPosition, num6 + (num5 / 2f)), new Point3D(x, (float)axisValue, num6 + (num5 / 2f)), new Point3D(x, (float)this.vAxis.GetPosition(point.YValues[2]), num6 + (num5 / 2f)), new Point3D(x, (float)this.vAxis.GetPosition(point.YValues[3]), num6 + (num5 / 2f)), new Point3D(x, (float)this.vAxis.GetPosition(point.YValues[4]), num6 + (num5 / 2f)), new Point3D(x, (float)this.vAxis.GetPosition(point.YValues[5]), num6 + (num5 / 2f)) };
					area.matrix3D.TransformPoints(points);
					if (common.ProcessModePaint)
					{
						bool flag3 = false;
						if ((xValue == this.hAxis.ViewMinimum) || (xValue == this.hAxis.ViewMaximum))
						{
							graph.SetClip(area.PlotAreaPosition.ToRectangleF());
							flag3 = true;
						}
						Color borderColor = point.BorderColor;
						if (borderColor == Color.Empty)
						{
							borderColor = point.Color;
						}
						graph.StartHotRegion(point);
						graph.DrawLineRel(borderColor, point.BorderWidth, point.BorderDashStyle, points[0].PointF, points[2].PointF, series.ShadowColor, series.ShadowOffset);
						graph.DrawLineRel(borderColor, point.BorderWidth, point.BorderDashStyle, points[1].PointF, points[3].PointF, series.ShadowColor, series.ShadowOffset);
						RectangleF empty = RectangleF.Empty;
						empty.X = points[0].X - (width / 2f);
						empty.Width = width;
						empty.Y = points[3].Y;
						empty.Height = Math.Abs((float)(empty.Y - points[2].Y));
						graph.FillRectangleRel(empty, point.Color, point.BackHatchStyle, point.BackImage, point.BackImageWrapMode, point.BackImageTransparentColor, point.BackImageAlignment, point.BackGradientStyle, point.BackSecondaryColor, point.BorderColor, point.BorderWidth, point.BorderDashStyle, series.ShadowColor, series.ShadowOffset, PenAlignment.Inset);
						bool flag4 = true;
						if (point.IsCustomPropertySet("BoxPlotShowAverage") || series.IsCustomPropertySet("BoxPlotShowAverage"))
						{
							string str2 = series["BoxPlotShowAverage"];
							if (point.IsCustomPropertySet("BoxPlotShowAverage"))
							{
								str2 = point["BoxPlotShowAverage"];
							}
							if (string.Compare(str2, "True", StringComparison.OrdinalIgnoreCase) != 0)
							{
								if (string.Compare(str2, "False", StringComparison.OrdinalIgnoreCase) != 0)
								{
									throw new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(point["BoxPlotShowAverage"], "BoxPlotShowAverage"));
								}
								flag4 = false;
							}
						}
						Color color = borderColor;
						if (color == point.Color)
						{
							if (Math.Sqrt((double)(((point.Color.R * point.Color.R) + (point.Color.G * point.Color.G)) + (point.Color.B * point.Color.B))) > 220.0)
							{
								color = ChartGraphics.GetGradientColor(point.Color, Color.Black, 0.4);
							}
							else
							{
								color = ChartGraphics.GetGradientColor(point.Color, Color.White, 0.4);
							}
						}
						if (!double.IsNaN(point.YValues[4]) && flag4)
						{
							graph.DrawLineRel(color, 1, ChartDashStyle.Solid, new PointF(empty.Left, points[4].Y), new PointF(empty.Right, points[4].Y), Color.Empty, 0);
						}
						bool flag5 = true;
						if (point.IsCustomPropertySet("BoxPlotShowMedian") || series.IsCustomPropertySet("BoxPlotShowMedian"))
						{
							string str3 = series["BoxPlotShowMedian"];
							if (point.IsCustomPropertySet("BoxPlotShowMedian"))
							{
								str3 = point["BoxPlotShowMedian"];
							}
							if (string.Compare(str3, "True", StringComparison.OrdinalIgnoreCase) != 0)
							{
								if (string.Compare(str3, "False", StringComparison.OrdinalIgnoreCase) != 0)
								{
									throw new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid(point["BoxPlotShowMedian"], "BoxPlotShowMedian"));
								}
								flag5 = false;
							}
						}
						if (!double.IsNaN(point.YValues[5]) && flag5)
						{
							float y = points[5].Y;
							float num16 = empty.Width / 9f;
							SizeF relativeSize = graph.GetRelativeSize(new SizeF(2f, 2f));
							num16 = Math.Max(num16, relativeSize.Width);
							for (float i = empty.Left; i < empty.Right; i += num16 * 2f)
							{
								graph.DrawLineRel(color, 1, ChartDashStyle.Solid, new PointF(i, y), new PointF(Math.Min(empty.Right, i + num16), y), Color.Empty, 0);
							}
						}
						this.DrawBoxPlotMarks3D(graph, area, series, point, x, width, num6, num5);
						x = points[0].X;
						axisValue = points[0].Y;
						linearPosition = points[1].Y;
						graph.EndHotRegion();
						if (flag3)
						{
							graph.ResetClip();
						}
					}
					if (common.ProcessModeRegions)
					{
						x = points[0].X;
						axisValue = points[0].Y;
						linearPosition = points[1].Y;
						RectangleF rectSize = RectangleF.Empty;
						rectSize.X = x - (width / 2f);
						rectSize.Y = (float)Math.Min(axisValue, linearPosition);
						rectSize.Width = width;
						rectSize.Height = ((float)Math.Max(axisValue, linearPosition)) - rectSize.Y;
						common.HotRegionsList.AddHotRegion(rectSize, point, series.Name, pointIndex - 1);
					}
					pointIndex++;
				}
				if (!selection)
				{
					pointIndex = 1;
					foreach (DataPoint point2 in series.Points)
					{
						float position = 0f;
						double num19 = point2.XValue;
						if (flag)
						{
							num19 = pointIndex;
							position = (((float)(this.hAxis.GetPosition((double)pointIndex) - ((width * count) / 2.0))) + (width / 2f)) + (num * width);
						}
						else if (showSideBySide)
						{
							position = (((float)(this.hAxis.GetPosition(num19) - ((width * count) / 2.0))) + (width / 2f)) + (num * width);
						}
						else
						{
							position = (float)this.hAxis.GetPosition(num19);
						}
						double num20 = this.vAxis.GetLogValue(point2.YValues[0]);
						double num21 = this.vAxis.GetLogValue(point2.YValues[1]);
						num19 = this.hAxis.GetLogValue(num19);
						if ((((num19 < this.hAxis.ViewMinimum) || (num19 > this.hAxis.ViewMaximum)) || ((num20 < this.vAxis.ViewMinimum) && (num21 < this.vAxis.ViewMinimum))) || ((num20 > this.vAxis.ViewMaximum) && (num21 > this.vAxis.ViewMaximum)))
						{
							pointIndex++;
							continue;
						}
						double viewMaximum = this.vAxis.GetLogValue(point2.YValues[1]);
						double viewMinimum = this.vAxis.GetLogValue(point2.YValues[0]);
						if (viewMaximum > this.vAxis.ViewMaximum)
						{
							viewMaximum = this.vAxis.ViewMaximum;
						}
						if (viewMaximum < this.vAxis.ViewMinimum)
						{
							viewMaximum = this.vAxis.ViewMinimum;
						}
						viewMaximum = (float)this.vAxis.GetLinearPosition(viewMaximum);
						if (viewMinimum > this.vAxis.ViewMaximum)
						{
							viewMinimum = this.vAxis.ViewMaximum;
						}
						if (viewMinimum < this.vAxis.ViewMinimum)
						{
							viewMinimum = this.vAxis.ViewMinimum;
						}
						viewMinimum = this.vAxis.GetLinearPosition(viewMinimum);
						Point3D[] pointdArray2 = new Point3D[] { new Point3D(position, (float)viewMaximum, num6 + (num5 / 2f)), new Point3D(position, (float)viewMinimum, num6 + (num5 / 2f)) };
						area.matrix3D.TransformPoints(pointdArray2);
						position = pointdArray2[0].X;
						viewMaximum = pointdArray2[0].Y;
						viewMinimum = pointdArray2[1].Y;
						this.DrawLabel(common, area, graph, series, point2, new PointF(position, (float)Math.Min(viewMaximum, viewMinimum)), pointIndex);
						pointIndex++;
					}
				}
				if (!selection)
				{
					common.Chart.CallOnPrePaint(new ChartPaintEventArgs(series, graph, common, area.PlotAreaPosition));
				}
			}
		}

		public virtual bool ApplyPaletteColorsToPoints
		{
			get
			{
				return false;
			}
		}

		public bool CircularChartArea
		{
			get
			{
				return false;
			}
		}

		public virtual bool DataPointsInLegend
		{
			get
			{
				return false;
			}
		}

		public virtual bool ExtraYValuesConnectedToYAxis
		{
			get
			{
				return true;
			}
		}

		public virtual bool HundredPercent
		{
			get
			{
				return false;
			}
		}

		public virtual bool HundredPercentSupportNegative
		{
			get
			{
				return false;
			}
		}

		public virtual string Name
		{
			get
			{
				return "BoxPlot";
			}
		}

		public virtual bool RequireAxes
		{
			get
			{
				return true;
			}
		}

		public bool SecondYScale
		{
			get
			{
				return false;
			}
		}

		public bool SideBySideSeries
		{
			get
			{
				return false;
			}
		}

		public virtual bool Stacked
		{
			get
			{
				return false;
			}
		}

		public bool StackSign
		{
			get
			{
				return false;
			}
		}

		public virtual bool SupportLogarithmicAxes
		{
			get
			{
				return true;
			}
		}

		public virtual bool SupportStackedGroups
		{
			get
			{
				return false;
			}
		}

		public virtual bool SwitchValueAxes
		{
			get
			{
				return false;
			}
		}

		public virtual int YValuesPerPoint
		{
			get
			{
				return 6;
			}
		}

		public virtual bool ZeroCrossing
		{
			get
			{
				return false;
			}
		}
	}
}

